package com.xq.shop.controller;


import com.xq.shop.service.IFileService;
import com.xq.shop.vo.FileVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import utils.BaseResult;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

/**
 * <p>
 * 文件表 前端控制器
 * </p>
 *
 * @author gaoxiaojin
 * @since 2024-07-16
 */
@Slf4j
@RestController
@RequestMapping("/file")
public class FileController {

    // 缓冲流大小（优化IO性能）
    private static final int BUFFER_SIZE = 4096;

    private final IFileService fileService;

    @Autowired
    public FileController(IFileService fileService) {
        this.fileService = fileService;
    }

    @RequestMapping("/upload")
    public BaseResult<FileVo> upload(@RequestParam("file") MultipartFile file) {
        BaseResult<FileVo> result = new BaseResult<>();
        result.initializeSuccess(fileService.upload(file));
        return result;
    }

    @RequestMapping("/uploadFile")
    public BaseResult<FileVo> uploadFile(@RequestParam("file") MultipartFile file) {
        BaseResult<FileVo> result = new BaseResult<>();
        result.initializeSuccess(fileService.uploadFile(file));
        return result;
    }

    /**
     * 图片代理接口
     * @param url 目标图片地址（需编码，如URLEncoder.encode(url, "UTF-8")）
     * @param response 响应对象，用于输出图片流
     */
    @GetMapping("/proxy/image")
    public void proxyImage(@RequestParam String url, HttpServletResponse response) {

        // 关闭Spring Boot的默认响应缓存（避免图片缓存问题）
        response.setHeader("Cache-Control", "no-store");
        response.setHeader("Pragma", "no-cache");
        response.setDateHeader("Expires", 0);

        // 创建HTTP客户端（使用Apache HttpClient）
        try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
            // 构建HTTP GET请求
            HttpGet httpGet = new HttpGet(url);
            // 设置请求头，模拟浏览器访问（部分服务器会拒绝爬虫请求）
            httpGet.setHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36");

            // 执行请求并获取响应
            try (CloseableHttpResponse httpResponse = httpClient.execute(httpGet)) {
                HttpEntity entity = httpResponse.getEntity();
                if (entity == null) {
                    log.error("目标图片URL返回空内容：{}", url);
                    response.sendError(HttpStatus.NOT_FOUND.value(), "图片不存在");
                    return;
                }

                // 获取目标图片的Content-Type（如image/jpeg、image/png），并设置到响应中
                String contentType = httpResponse.getFirstHeader("Content-Type").getValue();
                response.setContentType(contentType);

                // 获取图片输入流，并写入响应输出流
                try (InputStream inputStream = entity.getContent();
                     OutputStream outputStream = response.getOutputStream()) {

                    byte[] buffer = new byte[BUFFER_SIZE];
                    int bytesRead;
                    // 循环读取流并写入响应
                    while ((bytesRead = inputStream.read(buffer)) != -1) {
                        outputStream.write(buffer, 0, bytesRead);
                    }
                    // 刷新输出流，确保数据完整发送
                    outputStream.flush();
                }

            } catch (IOException e) {
                log.error("获取图片流失败，URL：{}", url, e);
                response.sendError(HttpStatus.INTERNAL_SERVER_ERROR.value(), "图片加载失败");
            }

        } catch (IOException e) {
            log.error("创建HTTP客户端失败", e);
        }
    }
}
